package com.cbg.bus.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.XmlUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cbg.base.constant.Constant;
import com.cbg.base.utils.Result;
import com.cbg.bus.entity.Order;
import com.cbg.bus.service.IOrderService;
import com.cbg.bus.utils.OrderUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.util.SignUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.cbg.base.core.SuperController;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import static com.cbg.bus.config.WXPayConfig.*;

/**
 * <p>
 * 订单表 前端控制器
 * </p>
 *
 * @author chenbing
 * @since 2018-12-19
 */
@RestController
@RequestMapping("/bus/order")
@Api(value = "订单控制器",tags = "订单操作接口")
public class OrderController extends SuperController<IOrderService, Order> {
    @Autowired
    private RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    IOrderService orderService;

    @ApiOperation(value="调起支付", notes="调起支付")
    @ApiImplicitParam(name = "outTradeNo", value = "订单号", required = true, dataType = "String",paramType = "query")
    @PostMapping("/pay")
    public Result<?> pay(String outTradeNo) {
        Map<String, String> result = new HashMap<>();
        try {
            Map<String, String> param = new HashMap<>();
            param.put("appid", appid);
            param.put("mch_id", mch_id);
            param.put("nonce_str", RandomUtil.randomStringUpper(32));
            param.put("body", body);
            param.put("out_trade_no", outTradeNo);
            param.put("total_fee", orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOutTradeNo, outTradeNo)).getTotal().multiply(new BigDecimal(100)).toString());
            param.put("spbill_create_ip", OrderUtils.ip(request()));
            param.put("notify_url", notify_url);
            param.put("trade_type", trade_type);
            String sign = SignUtils.createHmacSha256Sign(OrderUtils.createLinkString(param),key);
            param.put("sign", sign);
            XmlUtil.mapToXml(param, "xml");
            ResponseEntity<String> res = restTemplate().exchange(pay_url, HttpMethod.POST, null, String.class);
            Map<String, Object> map = XmlUtil.xmlToMap(res.getBody());
            //Map<String, String> result = new HashMap<>();
            if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
                String prepay_id = (String) map.get("prepay_id");
                result.put("appId", appid);
                String timeStamp = (System.currentTimeMillis() / 1000) + "";
                String nonceStr = RandomUtil.randomStringUpper(32);
                result.put("timeStamp", timeStamp);
                result.put("nonceStr", nonceStr);
                result.put("package", "prepay_id=" + prepay_id);
                result.put("signType", sign_type);
                String signStr = "appId=" + appid + "&nonceStr=" + nonceStr + "&package=prepay_id=" + prepay_id + "&signType=" + sign_type + "&timeStamp=" + timeStamp;
                String paySign = SignUtils.createHmacSha256Sign(signStr,key);
                result.put("paySign", paySign);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail();
        }
        return Result.ok(result);
    }

    @ApiOperation(value="微信回调URL", notes="微信回调URL")
    @GetMapping(value = "/wxNotify")
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        String notityXml = sb.toString();
        String resXml = "";
        Map<String, Object> map = XmlUtil.xmlToMap(notityXml);
        String returnCode = (String) map.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            Map<String, String> validParams = OrderUtils.paraFilter(map);
            String validStr = OrderUtils.createLinkString(validParams);
            String sign = SignUtils.createHmacSha256Sign(validStr, key);
            if (sign.equals(map.get("sign"))) {

                String outTradeNo= (String)map.get("out_trade_no");
                Order order = orderService.getOne(new LambdaQueryWrapper<Order>()
                        .eq(Order::getOutTradeNo, outTradeNo)).setStatus(Constant.IS_PAID);
                orderService.updateById(order);

                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }
}
